﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Linq;

using ProjectBase.Core;

namespace $safeprojectname$.Publishing.Handlers.ExceptionHandler
{
    public class ExceptionConfiguration
    {
        #region members
        IList<ExceptionSettings> _exceptions;
        EventLogEntryType? _eventLogEntryType = EventLogEntryType.Error;
        int _eventId = 9999;
        #endregion members

        #region public find
        public virtual ExceptionSettings FindSettings(Exception exception)
        {
            // mapped type
            var setting = Exceptions
                .FirstOrDefault(es => es.ExceptionType.Is()
                                      && es.ExceptionType.Equals(exception.GetType()));
            if (setting.Is())
            {
                return setting;
            }

            // try to find out some base
            var map = Exceptions.Where(es => es.ExceptionType.Is());
            setting = map
                .Where(es => IsDerived(es.ExceptionType, exception.GetType()))
                .FirstOrDefault();

            return setting;
        }
        protected virtual bool IsDerived(Type parent, Type child)
        {
            Contract.Requires(parent.Is());
            Contract.Requires(child.Is());

            var super = child.BaseType;
            while (super.Is())
            {
                if (super.IsEquivalentTo(parent))
                {
                    return true;
                }
                super = super.BaseType;
            }

            return false;
        }
        #endregion public find

        #region properties
        public virtual bool DoNotPublish { get; set; }
        public int DefaultEventId
        {
            get { return _eventId; }
            set { _eventId = value; }
        }
        public EventLogEntryType? DefaultEventLogEntryType
        {
            get { return _eventLogEntryType; }
            set { _eventLogEntryType = value; }
        }
        public virtual IList<ExceptionSettings> Exceptions
        {
            get { return _exceptions ?? (_exceptions = new List<ExceptionSettings>()); }
            set { _exceptions = value; }
        }
        #endregion properties
    }
    public class ExceptionSettings
    {
        EventLogEntryType? _eventLogEntryType = System.Diagnostics.EventLogEntryType.Error;

        public int EventId { get; set; }
        public EventLogEntryType? EventLogEntryType
        {
            get { return _eventLogEntryType; }
            set { _eventLogEntryType = value; }
        }

        public Type ExceptionType { get; set; }
    }
}
